local liquan = fk.CreateSkill{
  name = "plum__liquan",
}

local TuntianUtil = require "packages/tuntian_studio/utility"

Fk:loadTranslationTable{
  [liquan.name] = "力劝",
  [":"..liquan.name] = "出牌阶段限一次，你可令一名距离为1的角色选择一项："
  .."1.其发动“据守”并令你使用因此弃置的牌；"
  .."2.你发动“据守”并将因此弃置的牌当【杀】使用。"
  .."本回合你累计对两名角色造成伤害后，令因此发动“据守”的角色翻至正面。",

  ["#plum__liquan-prompt"] = "力劝：你可以令一名角色选择一项<br/>"
  .."1.其发动“据守”并令你使用因此弃置的牌；<br/>"
  .."2.你发动“据守”并将因此弃置的牌当【杀】使用。",
  ["#plum__liquan-self"] = "你发动“据守”并令 %src 使用因此弃置的牌",
  ["#plum__liquan-other"] = "%src 发动“据守”并将因此弃置的牌当【杀】使用",
  ["#plum__liquan-use"] = "力劝：请使用%arg",
  ["#plum__liquan-slash"] = "力劝：使用 %arg",

  ["plum__liquan-turn"] = "力劝",
}

liquan:addEffect("active", {
  anim_type = "defensive",
  prompt = "#plum__liquan-prompt",
  target_num = 1,
  card_num = 0,
  can_use = function(self, player)
    return player:usedSkillTimes(self.name, Player.HistoryPhase) == 0
  end,
  card_filter = Util.FalseFunc,
  target_filter = function (self, player, to_select, selected, selected_cards)
    return player:distanceTo(to_select) == 1
  end,
  on_use = function(self, room, effect)
    local player = effect.from
    local target = effect.tos[1]
    local choices = {"#plum__liquan-self:"..player.id, "#plum__liquan-other:"..player.id}
    local choice = room:askToChoice(target, {
      choices = choices,
      skill_name = liquan.name,
    })

    local proposer = (choice == choices[1]) and target or player
    TuntianUtil.triggerSkill("ol_ex__jushou", nil, proposer, proposer, nil)

    local card = player:getMark(liquan.name)
    if room:getCardArea(card) ~= Card.DiscardPile then return end
    room:setPlayerMark(player, liquan.name, 0)
    if card ~= 0 then
      if proposer ~= player then
        if #Fk:getCardById(card):getDefaultTarget(player, { extraUse = true }) > 0 then
          room:askToUseRealCard(player, {
            pattern = { card },
            prompt = "#plum__liquan-use:::"..Fk:getCardById(card):toLogString(),
            cancelable = false,
            skill_name = liquan.name,
            extra_data = {expand_pile = {card}}
          })
        end
      else
        local slash = Fk:cloneCard("slash")
        slash.skillName = liquan.name
        slash:addSubcard(card)
        local extra_data = { bypass_distances = true, bypass_times = true }
        if player:canUse(slash, extra_data) then
          local tos = room:askToChoosePlayers(player, {
            targets = table.filter(room.alive_players, function(p)
              return slash.skill:modTargetFilter(player, p, {}, slash, extra_data)
            end),
            min_num = 1,
            max_num = 1,
            cancelable = false,
            prompt = "#plum__liquan-slash:::"..slash:toLogString(),
            skill_name = liquan.name,
          })
          if #tos == 1 then
            room:useCard{
              card = slash,
              from = player,
              tos = tos,
              extraUse = true,
            }
          end
        end
      end
    end
  end,
})

---@param player ServerPlayer
---@param start integer
---@return boolean
local function harmTwo(player, start)
  local room = player.room
  local events = room.logic.all_game_events
  local suffers = {}
  for j = start, #events do
    if #suffers == 2 then break end
    if events[j].event == GameEvent.Damage then
      local data = events[j].data ---@type DamageData
      if data.from == player and data.damage > 0 then
        table.insertIfNeed(suffers, data.to)
      end
    end
  end
  return #suffers >= 2
end

---@param player ServerPlayer
---@return ServerPlayer[]
local function canTurnOverPlayers(player)
  local room = player.room
  local events = room.logic.all_game_events
  if not table.find(room.alive_players, function (p) return not p.faceup end) then return {} end
  local tos = {}

  for i = #events, 1, -1 do
    if events[i].event == GameEvent.SkillEffect then
      local data = events[i].data ---@type SkillEffectData
      if data.skill.name == "ol_ex__jushou" and not data.who.faceup then
        if events[i].parent and events[i].parent.event == GameEvent.SkillEffect then
          local p_data = events[i].parent.data ---@type SkillEffectData
          if p_data.skill.name == liquan.name and p_data.who == player and harmTwo(player, i) then
            table.insertIfNeed(tos, data.who)
          end
        end
      end
    elseif events[i].event == GameEvent.Turn then
      break
    end
  end
  return tos
end

liquan:addEffect(fk.Damage, {
  anim_type = "support",
  can_trigger = function (self, event, target, player)
    if player == target and player:hasSkill(liquan.name) then
      local tos = canTurnOverPlayers(player)
      if #tos == 0 then return end
      event:setCostData(self, tos)
      return true
    end
  end,
  on_cost = Util.TrueFunc,
  on_use = function (self, event, target, player, data)
    local room = player.room
    local tos = event:getCostData(self)
    if #tos == 0 then return end
    room:doIndicate(player, table.map(tos, Util.IdMapper))
    table.forEach(tos, function (p)
      if not p.faceup then
        p:turnOver()
      end
    end)
  end
})

liquan:addEffect(fk.AfterCardsMove, {
  can_refresh = function (self, event, target, player, data)
    if player ~= data[1].proposer then return end
    if data[1].skillName == "ol_ex__jushou" and data[1].moveReason == fk.ReasonDiscard then
      local grand_parent = player.room.logic:getCurrentEvent().parent.parent
      if grand_parent and grand_parent.data.skill.name == liquan.name then
        event:setCostData(self, grand_parent.data.who)
        return true
      end
    end
  end,
  on_refresh = function (self, event, target, player, data)
    local lihui = event:getCostData(self)
    player.room:setPlayerMark(lihui, liquan.name, data[1].moveInfo[1].cardId)
  end
})

return liquan